package evolution.operation.selection;

import evolution.individual.Individual;
import evolution.individual.IndividualSorter;
import evolution.random.RandomGenerator;

public class RankSelection implements SelectionStrategy {

	private RandomGenerator randomGenerator;

	@Override
	public Individual[] select(Individual[] source) {
		int length = source.length;

		int individualWeightSum = 0;
		int[] ranking = new int[length];

		IndividualSorter.sort(source);
		for (int i = 1; i <= length; i++) {
			individualWeightSum += i;
			ranking[length - i] = individualWeightSum;
		}

		Individual[] selected = new Individual[length];

		for (int i = 0; i < length; i++) {
			double random = randomGenerator.nextDouble() * individualWeightSum;

			int idx = 1;
			while (idx < length && random < ranking[idx]) {
				idx++;
			}
			selected[i] = source[idx - 1];
		}

		return selected;
	}

	public RandomGenerator getRandomGenerator() {
		return randomGenerator;
	}

	public void setRandomGenerator(RandomGenerator randomGenerator) {
		this.randomGenerator = randomGenerator;
	}
}
